import { ZRenderComp, Sprite } from '../../../common/component/zrComp';
import { gradientColor } from '../../../common/color/color';

import layout from './layout4';
import events from './events';
import { figures as figurePaths } from '../../../common/paths/fonts/timerFigures0';
import Timer from '../../../common/timer/Timer';

/**
 * zlevel = 20, 底
 * zlevel = 30, 数字
 */
class TimerPanel extends ZRenderComp {
	/** @type {Figure[]} 数字的数组, 记住, 计时器最右边的在 [0], [1] 是秒的个位... 共 6 位 */
	figures = [];
	/** @type {Figure[]} 0:点 1:分和秒间的冒号 2:时和分间的冒号 */
	points = [];
	showFigureCount = 0;

	figureStatic = {
		eachWidth : 30,
		firstWidth : 20,

		// 计时器有效文本数量(不包括标点) -> 文本总长度(包括标点)
		widthOfLength : [0, 18, 60, 90, 145, 175, 230],
		pointWidthOfLength : [36, 118, 203],

		firstScale : 0.06,
		eachScale : 0.09,
	};

	constructor(args) {
		super(args.parent);

		const {x, y, width:w, height:h, offset:o} = layout.timerPanel;
		this.useParentZRenderInstance(x, y);
		this.width = w;
		this.height = h;
		this.shapeOffset = o;
		/** @type {Timer} */
		this.timer = this.root.scoreBoard.timer;

		/** @type {string[]} */ this.figureColors = []; // length = 21
		for (let i = 0; i <= 20; i++) {
			this.figureColors.push(
				gradientColor(layout.colors.strokeNormal, 'white', i / 20).toHexRGB());
		}

		const w2 = w / 2, h2 = h / 2;
		// 起点是正上方, 方向顺时针
		this.hexagonPath = `M0-${h2}h${w2-o}l${o},${h2}l-${o},${h2}h-${w-2*o}l-${o}-${h2}l${o}-${h2}Z`;
		this.hexagonMag = 2 * (w - 2 * o) + 4 * Math.hypot(o, h2);

		// 数字
		let figureYEach = -34;
		let figureYFirst = figureYEach + 18;
		this.figures[0] = new Figure({ // ds 位
			parent: this, colors: this.figureColors,
			scale: this.figureStatic.firstScale, y: figureYFirst,
			chs: '0123456789'
		});
		this.figures[1] = new Figure({ // second 个位
			parent: this, colors: this.figureColors,
			scale: this.figureStatic.eachScale, y: figureYEach,
			chs: '0123456789'
		});
		this.figures[2] = new Figure({ // second 十位
			parent: this, colors: this.figureColors,
			scale: this.figureStatic.eachScale, y: figureYEach,
			chs: '012345'
		});
		this.figures[3] = new Figure({ // minute 个位
			parent: this, colors: this.figureColors,
			scale: this.figureStatic.eachScale, y: figureYEach,
			chs: '0123456789'
		});
		this.figures[4] = new Figure({ // minute 十位
			parent: this, colors: this.figureColors,
			scale: this.figureStatic.eachScale, y: figureYEach,
			chs: '012345'
		});
		this.figures[5] = new Figure({ // hour 个位
			parent: this, colors: this.figureColors,
			scale: this.figureStatic.eachScale, y: figureYEach,
			chs: '0123456789'
		});
		this.points[0] = new Figure({
			parent: this, colors: this.figureColors,
			scale: this.figureStatic.firstScale, y: figureYFirst,
			chs: '.'
		});
		this.points[1] = new Figure({
			parent: this, colors: this.figureColors,
			scale: this.figureStatic.eachScale, y: figureYEach,
			chs: ':'
		});
		this.points[2] = new Figure({
			parent: this, colors: this.figureColors,
			scale: this.figureStatic.eachScale, y: figureYEach,
			chs: ':'
		});

		this.on(events.TIMER_RESET, this.showCurtains.bind(this));
		this.on(events.TIMER_STOP, this.showCurtains.bind(this));
	}

	init() {
		// 底
		this.createPathFromString(this.hexagonPath)
			.stroke(layout.colors.strokeBgL1, 2)
			.fill(layout.colors.strokeBg)
			.z(20, 130)
			.build();

		// 边框
		this.spBound = this.createPathFromString(this.hexagonPath)
			.stroke(layout.colors.strokeNormal, 2)
			.fill('transparent')
			.shadow(layout.colors.strokeNormal, 15)
			.lineDash([this.hexagonMag, this.hexagonMag], 0)
			.z(30, 130)
			.build();

		// 帷幕
		const { offset:lo, height:lh } = layout.timerPanel;
		this.spLCurtain = this.createPolygon(
			[-lo / 3, lh / 2], [-lo / 3, lh / 2], [lo / 3, -lh / 2], [lo / 3, -lh / 2])
			.fill(layout.colors.strokeNormal)
			.z(30, 121)
			.build();
		const spLClip = this.createPathFromString(this.hexagonPath)
			.defineAsClip()
			.build();
		this.spLCurtain.setClipPath(spLClip);
		this.spLCurtain.hide();

		this.spRCurtain = this.createPolygon(
			[-lo / 3, lh / 2], [-lo / 3, lh / 2], [lo / 3, -lh / 2], [lo / 3, -lh / 2])
			.fill(layout.colors.strokeNormal)
			.z(30, 121)
			.build();
		const spRClip = this.createPathFromString(this.hexagonPath)
			.defineAsClip()
			.build();
		this.spRCurtain.setClipPath(spRClip);
		this.spRCurtain.hide();
	}

	tick(now) {
		super.tick(now);
		this.tickPanel();
		this.tickBound();
	}

	tickPanel() {
		const { timer } = this;

		let showCountNow = 0;
		if (timer.h != 0) {
			showCountNow = 6;
		} else if (timer.m > 9) {
			showCountNow = 5;
		} else if (timer.m > 0) {
			showCountNow = 4;
		} else {
			showCountNow = 3;
		}

		if (timer.h > 9) {
			this.figures[5].setCurrentCh('9');
			this.figures[4].setCurrentCh('5');
			this.figures[3].setCurrentCh('9');
			this.figures[2].setCurrentCh('5');
			this.figures[1].setCurrentCh('9');
			this.figures[0].setCurrentCh('9');
			this.points[2].setCurrentCh(':');
			this.points[1].setCurrentCh(':');
		} else {
			this.figures[5].setCurrentCh(showCountNow == 6 ? String(timer.h) : null);
			this.figures[4].setCurrentCh(showCountNow >= 5 ? String((timer.m / 10) | 0) : null);
			this.figures[3].setCurrentCh(showCountNow >= 4 ? String(timer.m % 10) : null);
			this.figures[2].setCurrentCh(String((timer.s / 10) | 0));
			this.figures[1].setCurrentCh(String(timer.s % 10));
			this.figures[0].setCurrentCh(String(timer.ds));
			this.points[2].setCurrentCh(showCountNow == 6 ? ':' : null);
			this.points[1].setCurrentCh(showCountNow >= 4 ? ':' : null);
			this.points[0].setCurrentCh('.');
		}

		if (showCountNow != this.showFigureCount) { // 需要移动位置
			this.showFigureCount = showCountNow;
			// 字串总长
			let textWidth = this.figureStatic.widthOfLength[showCountNow];
			for (let index = 0; index < showCountNow; index++) {
				this.figures[index].moveXTo(
					textWidth / 2 - this.figureStatic.widthOfLength[index + 1] - 5);
			}

			// 标点符号
			for (let index = 0; index < this.points.length; index++) {
				this.points[index].moveXTo(
					textWidth / 2 - this.figureStatic.pointWidthOfLength[index] - 5);
			}
		}
	}

	tickBound() {
		const {timer} = this;
		let second = timer.delta / 1000;

		this.spBound.sp.attr({
			style : {
				lineDashOffset : this.hexagonMag * (2 - (second % 12) / 6)
			}
		});
	}

	showCurtains() {
		const { offset:o, height:h, width:w } = layout.timerPanel;
		const {  spLCurtain, spRCurtain } = this;

		spLCurtain.stopAnimation(false);
		spLCurtain.attr({ shape : { points: [[-o/3, h/2], [-o/3, h/2], [o/3, -h/2], [o/3, -h/2] ] } });
		spLCurtain.show();
		spLCurtain.animate('shape')
			.when(150, { points: [ [-o/3, h/2], [-o/3-w/2, h/2], [o/3-w/2, -h/2], [o/3, -h/2] ] })
			.when(300, { points: [ [-o/3-w/2, h/2], [-o/3-w/2, h/2], [o/3-w/2, -h/2], [o/3-w/2, -h/2] ] })
			.done(() => {spLCurtain.hide()})
			.start();
		spRCurtain.stopAnimation(false);
		spRCurtain.attr({ shape : { points: [[-o/3, h/2], [-o/3, h/2], [o/3, -h/2], [o/3, -h/2] ] } });
		spRCurtain.show();
		spRCurtain.animate('shape')
			.when(150, { points: [ [-o/3, h/2], [-o/3+w/2, h/2], [o/3+w/2, -h/2], [o/3, -h/2] ] })
			.when(300, { points: [ [-o/3+w/2, h/2], [-o/3+w/2, h/2], [o/3+w/2, -h/2], [o/3+w/2, -h/2] ] })
			.done(() => {spRCurtain.hide()})
			.start();
	}
}

/**
 * 这个 component 移动的位置是父组件控制的, 一开始创建时位置就是 (0, args.y)
 * 需要父组件调用 moveXTo(x) 来移动.
 */
class Figure extends ZRenderComp {
	/** @type {string} 当前显示的字符. 为 null 表示不显示 */ currentCh = null;
	/** @type {string} 上一个显示的字符 */ lastCh = null;
	/** @type {number} 字符颜色在 this.colors 的指针 */ colorPtr = 0;

	constructor(args) {
		super(args.parent);
		this.useParentZRenderInstance(0, args.y);

		/** @type {number} */ this.scale = args.scale;
		/** @type {string} */ this.chs = args.chs;
		/** @type {string[]} */ this.colors = args.colors;

		/** @type {{ ch: string; sp: Sprite; }[]} */
		this.sps = [];
		for (let i = 0; i < this.chs.length; i++) {
			this.sps.push({ ch : this.chs[i], sp : null });
		}
	}

	init() {
		this.sps.forEach(p => {
			p.sp = this.createPathFromString(figurePaths[p.ch])
				.fill(this.colors[0])
				.shadow(this.colors[0], 11)
				.scale(this.scale, this.scale)
				.z(30, 120)
				.build();
			p.sp.hide();
			p.sp.anchor(130, 180);
		});
	}

	tick(now) {
		super.tick(now);
		if (this.colorPtr != 0) {
			this.colorPtr --;
			this.makeDirty(false);
		}
	}

	paint() {
		const [x, y] = this.relativePos();

		if (this.lastCh) {
			let sIdx = this.sps.findIndex(p => p.ch === this.lastCh);
			this.sps[sIdx].sp.hide();
			this.lastCh = null;
		}
		if (this.currentCh) {
			let sIdx = this.sps.findIndex(p => p.ch === this.currentCh);
			let sp = this.sps[sIdx].sp;
			sp.show();
			sp.sp.attr({
				style: {
					fill: this.colors[this.colorPtr],
					shadowColor: this.colors[this.colorPtr],
				},
				position: [x, y]
			});
		}
	}

	/**
	 * @param {string | null} ch 设置当前显示的字符
	 */
	setCurrentCh(ch) {
		if (ch === this.currentCh) {
			return;
		}
		this.lastCh = this.currentCh;
		this.currentCh = ch;
		this.colorPtr = this.colors.length;
		this.makeDirty(false);
	}

	moveXTo(x) {
		this.moveTo(x, this.y);
	}
}

export {
	TimerPanel
};
